<?php
/**
 * 核心函数库
 *
 * @author Dracowyn
 * @since 2023-11-13 17:56
 */

if (!function_exists('pre')) {
	/**
	 * 打印调试函数
	 * @param String|Array $data 需要打印的变量
	 * @return String 返回字符串结果
	 */
	function pre($data): string
	{
		echo '<pre>';
		var_dump($data);
		echo '</pre>';
		exit();
	}
}

// 数据库操作

if (!function_exists('all')) {
	/**
	 * 查询多条数据
	 * @param String $sql 查询语句
	 * @return Array 返回查询结果
	 */
	function all(string $sql): array
	{
		global $conn;
		$result = mysqli_query($conn, $sql);
		$data = [];
		if ($result && mysqli_num_rows($result) > 0) {
			$data = mysqli_fetch_all($result, MYSQLI_ASSOC);
		}
		return $data;
	}
}

if (!function_exists('find')) {
	/**
	 * 查询单条数据
	 * @param String $sql 查询语句
	 * @return Array 返回查询结果
	 */
	function find(string $sql): array
	{
		global $conn;
		$result = mysqli_query($conn, $sql);
		$data = [];
		if ($result && mysqli_num_rows($result) > 0) {
			$data = mysqli_fetch_assoc($result);
		}
		return $data;
	}
}

if (!function_exists('insert')) {
	/**
	 * 插入数据
	 * @param String $table 表名
	 * @param Array $data 插入的数据
	 * @param String $prefix_ 表前缀
	 * @return Array 返回结果集
	 */
	function insert(string $table, array $data, string $prefix_ = ''): array
	{
		global $conn, $prefix_;

		$prefix = $prefix ?? $prefix_;
		$table = $prefix . $table;
		// 从数组获取字段名
		$fields = array_keys($data);
		// 把数组转成字符串
		$fields_str = '`' . implode('`,`', $fields) . '`';
		// 从数组里获取字段值
		$values = "'" . implode("','", $data) . "'";
		$sql = "INSERT INTO $table ($fields_str) VALUES ($values)";
		$result = mysqli_query($conn, $sql);
		if (!$result) {
			return result(mysqli_error($conn), 0, $sql);
		}

		return result('插入成功', 1, ['id' => mysqli_insert_id($conn)]);
	}
}

if (!function_exists('update')) {
	/**
	 * 更新数据
	 * @param String $table 表名
	 * @param Array $data 更新的数据
	 * @param String $where 更新条件
	 * @param String $prefix_ 表前缀
	 * @return Array 返回结果集
	 */
	function update(string $table, array $data, string $where, string $prefix_ = ''): array
	{
		global $conn, $prefix_;
		$set = '';
		foreach ($data as $key => $value) {
			$set .= "$key = '$value',";
		}
		$set = rtrim($set, ',');
		$sql = "UPDATE $prefix_$table SET $set WHERE $where";
		$result = mysqli_query($conn, $sql);
		if (!$result) {
			return result(mysqli_error($conn), 0, $sql);
		}

		return result('更新成功', 1);
	}
}

if (!function_exists('del')) {
	/**
	 * 删除数据
	 * @param String $table 表名
	 * @param String $where 删除条件
	 * @param String $prefix_ 表前缀
	 * @return Array 返回结果集
	 */
	function del(string $table, string $where, string $prefix_ = ''): array
	{
		global $conn, $prefix_;
		$sql = "DELETE FROM $prefix_$table WHERE $where";
		$result = mysqli_query($conn, $sql);
		if (!$result) {
			return result(mysqli_error($conn), 0, $sql);
		}

		return result('删除成功', 1);
	}
}

if (!function_exists('execute')) {
	/**
	 * 执行增删改操作
	 * @param String $sql 查询语句
	 * @return Int 返回受影响的行数
	 */
	function execute(string $sql): int
	{
		global $conn;
		$result = mysqli_query($conn, $sql);
		$rows = 0;
		if ($result) {
			$rows = mysqli_affected_rows($conn);
		}
		return $rows;
	}
}


//一些操作

if (!function_exists('result')) {
	/**
	 * 返回结果集
	 * @param String $msg 提示信息
	 * @param String|Array|null $code 状态码
	 * @param String|Array|null $data 返回数据
	 * @return Array|null 返回结果集
	 */
	function result(string $msg = '未知信息', $code = 0, $data = null): array
	{
		return [
			'code' => $code,
			'msg' => $msg,
			'data' => $data
		];
	}
}

if (!function_exists('showMsg')) {
	/**
	 * 跳转并且提示函数
	 * @param String $msg 提示信息
	 * @param string|null $url 跳转地址
	 */
	function showMsg(string $msg = '未知信息', string $url = null): void
	{
		if ($url) {
			echo "<script>alert('$msg');location.href='$url'</script>";
		} else {
			echo "<script>alert('$msg');history.back()</script>";
		}
		exit();
	}
}

/**
 * 生成随机字符串
 */
if (!function_exists('randStr')) {
	/**
	 * 生成随机字符串
	 * @param int $len 需要的长度
	 * @param bool $special 是否需要特殊符号
	 * @return String 返回生成的随机字符串
	 */
	function randStr(int $len = 8, bool $special = false): string
	{
		$chars = array(
			'abcdefghijklmnopqrstuvwxyz',
			'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
			'0123456789'
		);
		if ($special) {
			$chars[] = '!@#$%^&*()_+-=[]{}|';
		}
		$chars = implode('', $chars);
		$chars = str_shuffle($chars);
		return substr($chars, 0, $len);
	}
}

if (!function_exists('upload')) {
	/**
	 * 上传单图
	 * @param String $name 图片名
	 * @param String $filePath 保存文件路径
	 * @param Array $allowType 图片格式类型
	 * @param Int $size 图片大小
	 * @return Array 返回处理结果
	 */
	function upload(string $name, string $filePath = 'upload', array $allowType = ['jpg', 'jpeg', 'png', 'gif'], int $size = 1024 * 1024 * 2): array
	{
		if (!is_dir($filePath)) {
			mkdir($filePath, 0755, true);
		}
		$errorCode = $_FILES[$name]['error'] ?? 4;
		switch ($errorCode) {
			case 1:
				return result(0, '上传大小不能超过upload_max_filesize设置的值');
			case 2:
				return result(0, '上传大小不能超过MAX_FILE_SIZE设置的值');
			case 3:
				return result(0, '图片上传不完整');
			case 4:
				return result(0, '没有文件上传');
			case 6:
			case 7:
				return result(0, '服务器错误');
		}

		$ext = pathinfo($_FILES[$name]['name'], PATHINFO_EXTENSION);

		if (!in_array($ext, $allowType)) {
			return result(0, '图片格式不正确');
		}

		$fileSize = $_FILES[$name]['size'] ?? 0;
		if ($fileSize > $size) {
			return result(0, '图片过大');
		}

		$filename = date('YmdHis', time()) . mt_rand(1000, 9999) . mt_rand(1000, 9999) . '.' . $ext;
		if (is_uploaded_file($_FILES[$name]['tmp_name'])) {
			if (move_uploaded_file($_FILES[$name]['tmp_name'], $filePath . '/' . $filename)) {
				return result(1, '上传成功', ['filename' => $filename]);
			} else {
				return result(0, '上传失败');
			}
		} else {
			return result(0, '非法上传');
		}
	}
}

if (!function_exists('check_auth')) {
	/**
	 * 检测用户是否登录
	 * @return Array 返回用户信息
	 */
	function check_auth(): array
	{
		$loginAuth = isset($_COOKIE['loginAuth']) ? json_decode($_COOKIE['loginAuth'], true) : [];
		if (!$loginAuth) {
			showMsg('请先登录', 'login.php');
		}

		$id = $loginAuth['id'] ?? 0;
		$username = $loginAuth['username'] ?? '';

		$sql = "SELECT * FROM pre_admin WHERE id = $id AND username = '$username'";

		$admin = find($sql);

		if (!$admin) {
			setcookie('loginAuth', '', time() - 1);
			showMsg('非法登录', 'login.php');
		}

		$data = [
			'id' => $admin['id'],
			'username' => $admin['username'],
			'avatar' => $admin['avatar'],
		];

		setcookie('loginAuth', json_encode($data), time() + 3600 * 24 * 7);

		return $data;
	}
}

if (!function_exists('success')) {
	/**
	 * 返回请求成功的数据
	 * @param String $msg 提示信息
	 * @param Array|null $data 返回数据
	 * @param Int $code 状态码
	 */
	function success(string $msg = '未知信息', array $data = null, int $code = 1)
	{
		echo json_encode(result($msg, $code, $data));
		exit;
	}
}

if (!function_exists('error')) {
	/**
	 * 返回请求失败的数据
	 * @param String $msg 提示信息
	 * @param Array|null $data 返回数据
	 * @param Int $code 状态码
	 */
	function error(string $msg = '未知信息', array $data = null, int $code = 0)
	{
		echo json_encode(result($msg, $code, $data));
		exit;
	}
}

if (!function_exists('getUrl')) {
	/**
	 * 获取重新组装的URL
	 * @return String 返回URL
	 */
	function getUrl(): string
	{
		$url = $_SERVER['PHP_SELF'] . '?';
		if ($_GET) {
			foreach ($_GET as $key => $value) {
				if ($key != 'page') {
					$url .= $key . '=' . $value . '&';
				}
			}
		}
		return $url;
	}
}

if (!function_exists('showPage')) {
	/**
	 * 输出分页结构的函数
	 * @param String|Int $current 当前页
	 * @param String|Int $count 数据总行数
	 * @param Int $limit 每页显示的多少条数据
	 * @param Int $size 显示多少个页码
	 * @param String $class 样式选择符名
	 * @return String 返回分页结构
	 */
	function showPage($current, $count, int $limit = 10, int $size = 5, string $class = 'digg'): string
	{
		// 计算总页数
		$total = ceil($count / $limit);
		// 计算偏移量
		$offset = floor($size / 2);
		// 计算起始页
		$start = $current - $offset;
		// 计算结束页
		$end = $current + $offset;
		// 判断起始页
		if ($start <= 1) {
			$start = 1;
			$end = $start + $size - 1;
		}
		// 判断结束页
		if ($end >= $total) {
			$end = $total;
			$start = $end - $size + 1;
			if ($start <= 1) {
				$start = 1;
			}
		}
		// 拼接分页结构
		$page = '<ul class="' . $class . '">';
		// 判断是否显示上一页
		if ($current > 1) {
			$page .= '<li><a href="' . getUrl() . 'page=' . ($current - 1) . '">上一页</a></li>';
		}
		// 判断是否显示首页
		if ($start > 1) {
			$page .= '<li><a href="' . getUrl() . 'page=1">首页</a></li>';
		}
		// 循环显示页码
		for ($i = $start; $i <= $end; $i++) {
			// 判断是否是当前页
			if ($i == $current) {
				$page .= '<li class="active"><a href="' . getUrl() . 'page=' . $i . '">' . $i . '</a></li>';
			} else {
				$page .= '<li><a href="' . getUrl() . 'page=' . $i . '">' . $i . '</a></li>';
			}
		}
		// 判断是否显示尾页
		if ($end < $total) {
			$page .= '<li><a href="' . getUrl() . 'page=' . $total . '">尾页</a></li>';
		}
		// 判断是否显示下一页
		return $page;
	}
}